package com.walnut.lom_system.common.util;

import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.walnut.lom_system.common.lang.Const;
import com.walnut.lom_system.domain.dto.ExcelUserInfoDto;
import com.walnut.lom_system.domain.entity.UserInfo;
import lombok.Builder;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.apache.poi.ss.formula.functions.T;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;

import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.function.Function;

/**
 * @author chenhetao
 * @description 单体/列表复制工具类
 * @create 2021/11/8 19:54
 */
@Component
@Slf4j
public class CopyUtil {
    public static <T> T copy(Object source, Class<T> clazz, Class clazzSource) {
        T obj = copy(source, clazz);
        //填坑！phone字段
        try {
//暴力反射获取字段

            Field field1 = clazz.getDeclaredField("phone");
            Field field2 = clazzSource.getDeclaredField("phone");
            field1.setAccessible(true);
            field2.setAccessible(true);


            if (field2.getType().equals(Long.class)) {
                log.warn("尝试修改phone字段(String -> Long)");
                field1.set(obj, String.valueOf(field2.get(source)));
            } else {
                log.warn("尝试修改phone字段(Long -> String)");
                field1.set(obj, Long.valueOf((String) field2.get(source)));
            }

        } catch (Exception e) {
            e.printStackTrace();
        }
        return obj;
    }

    /**
     * 单体复制
     *
     * @param source 原数据
     * @param clazz  类
     * @param <T>    返回类型
     * @return 返回复制后的bean
     */
    public static <T> T copy(Object source, Class<T> clazz) {
        if (source == null) {
            return null;
        }
        T obj;
        try {
            obj = clazz.getDeclaredConstructor().newInstance();
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
        BeanUtils.copyProperties(source, obj);
        return obj;
    }

    /**
     * 列表复制
     *
     * @param source 原数据
     * @param clazz  类
     * @param <T>    返回类型
     * @return 返回复制后的bean
     */
    public static <T> List<T> copyList(List source, Class<T> clazz) {
        List<T> target = new ArrayList<>();
        if (!CollectionUtils.isEmpty(source)) {
            for (Object c : source) {
                T obj = copy(c, clazz);
                target.add(obj);
            }
        }
        return target;
    }

    public static List<UserInfo> copyListUserFromExcel(List<ExcelUserInfoDto> excelUserInfoDtos) {
        List<UserInfo> userInfos = new ArrayList<>();

        if (!CollectionUtils.isEmpty(excelUserInfoDtos)) {
            for (ExcelUserInfoDto c : excelUserInfoDtos) {
                //TODO 单体复制
                UserInfo userInfo = copyUserFromExcel(c);
                userInfos.add(userInfo);
            }
        }


        return userInfos;
    }

    /**
     * 项目中的excel实体类复制
     *
     * @param source 原数据
     * @return 返回bean
     */
    public static UserInfo copyUserFromExcel(ExcelUserInfoDto source) {
        UserInfo userInfo = null;
        if (source == null) {
            return null;
        }
        userInfo = UserInfo.builder().
                academy(source.getAcademy()).
                name(source.getName()).
                userSid(Long.valueOf(source.getUserSid())).
                gender("男".equals(source.getGender()) ? 1 : "女".equals(source.getGender()) ? 0 : -1).
                classNo(Integer.valueOf(source.getClassNo())).
                phone(Long.valueOf(source.getPhone())).
                qq(Long.valueOf(source.getQq())).
                createTime(new Date()).
                lastEditTime(new Date()).
                deleted(0).
                state(Const.USER_ON_USE).
                build();
        System.out.println(userInfo);
        return userInfo;
    }


    /**
     * 用于PageDTO 到 PageVO 的转换
     *
     * @param source 原数据
     * @param clazz  需要转换后的Vo类
     * @param <VO>   VO
     * @param <DTO>  DTO
     * @return 转换后的page对象
     */
    public static <VO, DTO> Page<VO> dto2Vo(Page<DTO> source, Class<VO> clazz) {
        Page<VO> voPage = new Page<>();
        BeanUtils.copyProperties(source, voPage);
        List<DTO> records = source.getRecords();
        List<VO> VOList = copyList(records, clazz);
        voPage.setRecords(VOList);
        return voPage;
    }


}